﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="NewsInformationController.cs" company="DissingNellemann">
//   
// All rights reserved </copyright>
// <summary>
//   The news information controller.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Website.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Threading;
    using System.Web;
    using System.Web.Mvc;
    using Website.CRUDServices;
    using Website.Models;
    using Website.Models.Styling;
    using Website.Models.ViewModels;
    using File = Website.CRUDServices.File;
    using User = Website.Models.Domain.User;

    /// <summary>
    ///     The news information controller.
    /// </summary>
    [Authorize(Roles = "User, Admin")]
    public class NewsInformationController : BaseController
    {
        // GET: /NewsInformation/
        #region Public Methods and Operators

        /// <summary>
        ///     The get header items.
        /// </summary>
        /// <returns>
        ///     The list of headeritems for a newsinformation view.
        /// </returns>
        public static List<TableViewHeaderItem> GetHeaderItems()
        {
            var headerItems = new List<TableViewHeaderItem>();
            var item1 = new TableViewHeaderItem { Text = "Dato", SortableName = "TimeOfActivity", IsSortable = true, };
            var item2 = new TableViewHeaderItem { Text = "Overskrift", SortableName = "Name", IsSortable = true };
            var item3 = new TableViewHeaderItem { Text = "Nyhedstype", SortableName = "Type", IsSortable = true };
            var item4 = new TableViewHeaderItem { Text = "Beskrivelse", SortableName = string.Empty, IsSortable = false };

            headerItems.Add(item1);
            headerItems.Add(item2);
            headerItems.Add(item3);
            headerItems.Add(item4);

            return headerItems;
        }

        /// <summary>
        /// The index.
        /// </summary>
        /// <param name="skip">
        /// The skip.
        /// </param>
        /// <param name="take">
        /// The take.
        /// </param>
        /// <param name="orderBy">
        /// The order by.
        /// </param>
        /// <param name="sortAscending">
        /// The sort ascending.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        public ActionResult Index(int? skip, int? take, string orderBy, bool? sortAscending)
        {
            this.Session["CurrentSubMenuSelection"] = "NewsInformation";
            ListView<NewsInformation> view = null;

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var activities = new List<NewsInformation>();
                    var query = new NewsInformationQuery();
                    query.Settings = new SearchSettings
                    {
                        SortAscending =
                            sortAscending ?? false,
                        Skip = skip ?? 0,
                        Take = take ?? 20,
                        OrderBy =
                            !string.IsNullOrEmpty(orderBy)
                                ? orderBy
                                : "TimeOfActivity"
                    };

                    IResult iRes = client.Query(query);
                    if (iRes != null)
                    {
                        var res = (NewsInformationResult)iRes;
                        view = new ListView<NewsInformation>(
                            res.List.ToList(),
                            skip ?? 0,
                            take ?? 20,
                            res.TotalRowCount,
                            query.Settings.OrderBy,
                            sortAscending ?? false,
                            GetHeaderItems(),
                            "Index");
                    }
                });

            this.ViewData["Types"] = PrimitiveTypes.GetNewsInformationTypes();
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();

            return View(view);
        }

        /// <summary>
        ///     The new news information.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        public ActionResult NewNewsInformation()
        {
            this.ViewData["Funds"] = PrimitiveTypes.GetFunds();
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            this.ViewData["Types"] = PrimitiveTypes.GetNewsInformationTypes();
            return this.View();
        }

        /// <summary>
        /// The new news information.
        /// </summary>
        /// <param name="news">
        /// The news.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        [HttpPost]
        [ValidateInput(false)] 
        public ActionResult NewNewsInformation(NewsInformationModel news)
        {
            // transfer to the DTO
            var dto = new NewsInformation
            {
                ArchiveLocation = news.ArchiveLocation,
                Comments = news.Comments,
                Creator = (this.Session["LoggedInUser"] as User).ID,
                ID = Guid.NewGuid(),
                Name = news.Name,
                TimeOfActivity = news.TimeOfActivity,
                Type = news.Type,
            };
            if (news.OwnerProjects != null)
            {
                dto.OwnerProjects = news.OwnerProjects.ToArray();
            }

            if (news.Funds != null)
            {
                dto.Funds = news.Funds.ToArray();
            }

            if (news.informationType != null)
            {
                if (news.informationType.Contains("funds"))
                {
                    dto.IsInformationAboutFunds = true;
                }

                if (news.informationType.Contains("progress"))
                {
                    dto.IsInformationAboutProgress = true;
                }

                if (news.informationType.Contains("results"))
                {
                    dto.IsInformationAboutResults = true;
                }
            }

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var cmds = new List<ICommand>();

                    // check for files
                    if (news.Files != null)
                    {
                        var crudFiles = new List<Guid>();
                        foreach (HttpPostedFileBase file in news.Files)
                        {
                            if (file != null)
                            {
                                var dtoFile = new File
                                {
                                    ID = Guid.NewGuid(),
                                    ContentType = file.ContentType,
                                    Name =
                                        file.FileName.Contains('\\')
                                            ? file.FileName.Substring(
                                                file.FileName.LastIndexOf('\\') + 1)
                                            : file.FileName
                                };

                                using (var memstream = new MemoryStream())
                                {
                                    file.InputStream.CopyTo(memstream);
                                    dtoFile.ContentData = memstream.ToArray();
                                }

                                crudFiles.Add(dtoFile.ID);

                                var cfm = new CreateFileCommand { NewFile = dtoFile };
                                cmds.Add(cfm);
                            }
                        }

                        dto.Files = crudFiles.ToArray();
                    }

                    // save the DTO
                    var ccmd = new CreateNewsInformationCommand { Dto = dto };
                    cmds.Add(ccmd);
                    client.ExecuteBatchsCommands(cmds.ToArray());
                });

            return this.RedirectToAction("Index");
        }

        /// <summary>
        /// The update news information.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        public ActionResult UpdateNewsInformation(Guid id)
        {
            // set data for lists
            this.ViewData["Funds"] = PrimitiveTypes.GetFunds();
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            this.ViewData["Types"] = PrimitiveTypes.GetNewsInformationTypes();
            

            // load object for editing
            var dto = new NewsInformation();
            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var query = new NewsInformationQuery { Settings = new SearchSettings { IDEquals = id } };

                    var res = client.Query(query) as NewsInformationResult;
                    if (res != null)
                    {
                        if (res.List.Any())
                        {
                            dto = res.List[0];
                            this.ViewData["FilesInfo"] = PrimitiveTypes.GetFilesWithoutBytesWithIDs((dto.Files ?? new Guid[0]).ToList());
                        }
                    }
                });

            // ensure we have some content
            if (dto != null)
            {
                return View(dto);
            }

            // something buggered up. Better send them back to the index.
            return this.RedirectToAction("Index");
        }

        /// <summary>
        /// The update news information.
        /// </summary>
        /// <param name="news">
        /// The news.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        [HttpPost]
        [ValidateInput(false)] 
        public ActionResult UpdateNewsInformation(NewsInformationModel news)
        {
            // transfer to the DTO
            var dto = new NewsInformation
            {
                ArchiveLocation = news.ArchiveLocation,
                Comments = news.Comments,
                Creator = (this.Session["LoggedInUser"] as User).ID,
                ID = news.ID,
                Name = news.Name,
                TimeOfActivity = news.TimeOfActivity,
                Type = news.Type,
            };
            if (news.OwnerProjects != null)
            {
                dto.OwnerProjects = news.OwnerProjects.ToArray();
            }

            if (news.Funds != null)
            {
                dto.Funds = news.Funds.ToArray();
            }

            if (news.informationType != null)
            {
                if (news.informationType.Contains("funds"))
                {
                    dto.IsInformationAboutFunds = true;
                }

                if (news.informationType.Contains("progress"))
                {
                    dto.IsInformationAboutProgress = true;
                }

                if (news.informationType.Contains("results"))
                {
                    dto.IsInformationAboutResults = true;
                }
            }

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var cmds = new List<ICommand>();

                    // check for files
                    if (news.Files != null)
                    {
                        var oldFilesQuery = (Website.CRUDServices.NewsInformationResult)client.Query(new NewsInformationQuery
                        {
                             Settings = new SearchSettings { IDEquals = news.ID } 
                        });

                        var crudFiles = new List<Guid>();

                        if (oldFilesQuery != null && oldFilesQuery.TotalRowCount > 0 && oldFilesQuery.List[0].Files != null)
                        {
                            crudFiles.AddRange(oldFilesQuery.List[0].Files);
                        }

                        
                        foreach (HttpPostedFileBase file in news.Files)
                        {
                            if (file != null)
                            {
                                var dtoFile = new File
                                {
                                    ID = Guid.NewGuid(),
                                    ContentType = file.ContentType,
                                    Name =
                                        file.FileName.Contains('\\')
                                            ? file.FileName.Substring(
                                                file.FileName.LastIndexOf('\\') + 1)
                                            : file.FileName
                                };

                                using (var memstream = new MemoryStream())
                                {
                                    file.InputStream.CopyTo(memstream);
                                    dtoFile.ContentData = memstream.ToArray();
                                }

                                crudFiles.Add(dtoFile.ID);

                                var cfm = new CreateFileCommand { NewFile = dtoFile };
                                cmds.Add(cfm);
                            }
                        }

                        if (dto.Files != null)
                        {
                            crudFiles.AddRange(dto.Files);
                        }

                        dto.Files = crudFiles.ToArray();
                    }

                    // save the DTO
                    var ccmd = new UpdateNewsInformationCommand { Dto = dto };

                    cmds.Add(ccmd);
                    client.ExecuteBatchsCommands(cmds.ToArray());
                });

            return this.RedirectToAction("Index");
        }


        public ActionResult DeleteNewsInformationFileJson(Guid OwnerNewsID, Guid FileID)
        {
            CRUDServiceProvider.WithCRUDService(client =>
                {
                    DeleteNewsInformationFileCommand cmd = new DeleteNewsInformationFileCommand()
                    {
                        FileID = FileID,
                        OwnerNewsID = OwnerNewsID
                    };
                    client.ExecuteCommand(cmd);
                });

            return this.Json(new { success = true });
        }

        public ActionResult DeleteNewsInformation(Guid id)
        {
            CRUDServiceProvider.WithCRUDService(client =>
            {
                CRUDServices.DeleteNewsInformationCommand cmd = new DeleteNewsInformationCommand() { Dto = id };
                client.ExecuteCommand(cmd);
            });

            return RedirectToAction("Index");
        }

        public ActionResult ViewNewsInformation(Guid id)
        {
            this.Init("Events");
            this.Session["SubMenuItems"] = ActivityController.CreateSubMenu();
            this.Session["CurrentSubMenuSelection"] = "NewsInformation";

            // set data for lists
            this.ViewData["Funds"] = PrimitiveTypes.GetFunds();
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            this.ViewData["Types"] = PrimitiveTypes.GetNewsInformationTypes();


            // load object for editing
            var dto = new NewsInformation();
            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var query = new NewsInformationQuery { Settings = new SearchSettings { IDEquals = id } };

                    var res = client.Query(query) as NewsInformationResult;
                    if (res != null)
                    {
                        if (res.List.Any())
                        {
                            dto = res.List[0];
                            this.ViewData["FilesInfo"] = PrimitiveTypes.GetFilesWithoutBytesWithIDs((dto.Files ?? new Guid[0]).ToList());
                        }
                    }
                });

            // ensure we have some content
            if (dto != null)
            {
                return View(dto);
            }

            // something buggered up. Better send them back to the index.
            return this.RedirectToAction("Index");
        }

        #endregion
    }
}